/**
 * 数组模块 - 借鉴Lodash的数组处理理念
 * 提供各种数组操作和处理功能
 */

/**
 * 检查是否为数组
 * @param {any} value 要检查的值
 * @returns {boolean} 是否为数组
 */
export function isArray(value) {
  return Array.isArray(value);
}

/**
 * 数组去重
 * @param {Array} arr 数组
 * @param {string|Function} key 对象属性名或比较函数（可选）
 * @returns {Array} 去重后的数组
 */
export function unique(arr, key) {
  if (!isArray(arr)) return [];

  // 如果没有提供key，使用基础去重
  if (!key) {
    return [...new Set(arr)];
  }

  // 如果是字符串key，按属性去重
  if (typeof key === 'string') {
    const seen = new Set();
    return arr.filter(item => {
      const value = item && item[key];
      if (seen.has(value)) return false;
      seen.add(value);
      return true;
    });
  }

  // 如果是函数，按函数结果去重
  if (typeof key === 'function') {
    const seen = new Set();
    return arr.filter(item => {
      const value = key(item);
      if (seen.has(value)) return false;
      seen.add(value);
      return true;
    });
  }

  return [...new Set(arr)];
}

/**
 * 数组去重（支持对象）
 * @param {Array} arr 数组
 * @param {string|Function} key 对象属性名或比较函数
 * @returns {Array} 去重后的数组
 */
export function uniqueBy(arr, key) {
  if (!isArray(arr)) return [];

  if (typeof key === 'string') {
    const seen = new Set();
    return arr.filter(item => {
      const value = item && item[key];
      if (seen.has(value)) return false;
      seen.add(value);
      return true;
    });
  }

  if (typeof key === 'function') {
    const seen = new Set();
    return arr.filter(item => {
      const value = key(item);
      if (seen.has(value)) return false;
      seen.add(value);
      return true;
    });
  }

  return unique(arr);
}

/**
 * 数组扁平化
 * @param {Array} arr 数组
 * @param {number} depth 深度
 * @returns {Array} 扁平化后的数组
 */
export function flatten(arr, depth = Infinity) {
  if (!isArray(arr)) return [];

  if (depth <= 0) return arr.slice();
  if (depth === Infinity) return arr.flat(Infinity);

  return arr.reduce((acc, val) => {
    if (isArray(val)) {
      acc.push(...flatten(val, depth - 1));
    } else {
      acc.push(val);
    }
    return acc;
  }, []);
}

/**
 * 数组深度扁平化
 * @param {Array} arr 数组
 * @returns {Array} 扁平化后的数组
 */
export function flattenDeep(arr) {
  if (!isArray(arr)) return [];
  return arr.flat(Infinity);
}

/**
 * 数组分块
 * @param {Array} arr 数组
 * @param {number} size 块大小
 * @returns {Array} 分块后的二维数组
 */
export function chunk(arr, size = 1) {
  if (!isArray(arr) || size <= 0) return [];

  const result = [];
  for (let i = 0; i < arr.length; i += size) {
    result.push(arr.slice(i, i + size));
  }
  return result;
}

/**
 * 数组分组
 * @param {Array} arr 数组
 * @param {string|Function} key 分组键或函数
 * @returns {Object} 分组后的对象
 */
export function groupBy(arr, key) {
  if (!isArray(arr)) return {};

  return arr.reduce((groups, item) => {
    const groupKey = typeof key === 'function' ? key(item) : item[key];
    const group = groups[groupKey] || [];
    group.push(item);
    groups[groupKey] = group;
    return groups;
  }, {});
}

/**
 * 数组统计
 * @param {Array} arr 数组
 * @param {string|Function} key 统计键或函数
 * @returns {Object} 统计结果
 */
export function countBy(arr, key) {
  if (!isArray(arr)) return {};

  return arr.reduce((counts, item) => {
    const countKey = typeof key === 'function' ? key(item) : item[key];
    counts[countKey] = (counts[countKey] || 0) + 1;
    return counts;
  }, {});
}

/**
 * 数组排序
 * @param {Array} arr 数组
 * @param {string[]|Function[]} keys 排序键或函数数组
 * @param {string[]} orders 排序方向数组 ('asc' | 'desc')
 * @returns {Array} 排序后的数组
 */
export function orderBy(arr, keys = [], orders = []) {
  if (!isArray(arr)) return [];
  if (!isArray(keys)) keys = [keys];
  if (!isArray(orders)) orders = [orders];

  return arr.slice().sort((a, b) => {
    for (let i = 0; i < keys.length; i++) {
      const key = keys[i];
      const order = orders[i] || 'asc';

      const aVal = typeof key === 'function' ? key(a) : a[key];
      const bVal = typeof key === 'function' ? key(b) : b[key];

      if (aVal < bVal) {
        return order === 'desc' ? 1 : -1;
      }
      if (aVal > bVal) {
        return order === 'desc' ? -1 : 1;
      }
    }
    return 0;
  });
}

/**
 * 查找数组项
 * @param {Array} arr 数组
 * @param {Function|Object} predicate 查找条件
 * @returns {any} 找到的项
 */
export function find(arr, predicate) {
  if (!isArray(arr)) return undefined;

  if (typeof predicate === 'function') {
    return arr.find(predicate);
  }

  if (typeof predicate === 'object') {
    return arr.find(item => {
      return Object.keys(predicate).every(key => item[key] === predicate[key]);
    });
  }

  return undefined;
}

/**
 * 查找数组项索引
 * @param {Array} arr 数组
 * @param {Function|Object} predicate 查找条件
 * @returns {number} 索引
 */
export function findIndex(arr, predicate) {
  if (!isArray(arr)) return -1;

  if (typeof predicate === 'function') {
    return arr.findIndex(predicate);
  }

  if (typeof predicate === 'object') {
    return arr.findIndex(item => {
      return Object.keys(predicate).every(key => item[key] === predicate[key]);
    });
  }

  return -1;
}

/**
 * 过滤数组
 * @param {Array} arr 数组
 * @param {Function|Object} predicate 过滤条件
 * @returns {Array} 过滤后的数组
 */
export function filter(arr, predicate) {
  if (!isArray(arr)) return [];

  if (typeof predicate === 'function') {
    return arr.filter(predicate);
  }

  if (typeof predicate === 'object') {
    return arr.filter(item => {
      return Object.keys(predicate).every(key => item[key] === predicate[key]);
    });
  }

  return arr.slice();
}

/**
 * 数组求和
 * @param {Array} arr 数组
 * @param {string|Function} key 求和字段或函数
 * @returns {number} 和
 */
export function sumBy(arr, key) {
  if (!isArray(arr)) return 0;

  return arr.reduce((sum, item) => {
    const value = typeof key === 'function' ? key(item) : (key ? item[key] : item);
    return sum + (Number(value) || 0);
  }, 0);
}

/**
 * 数组求平均值
 * @param {Array} arr 数组
 * @param {string|Function} key 字段或函数
 * @returns {number} 平均值
 */
export function meanBy(arr, key) {
  if (!isArray(arr) || arr.length === 0) return 0;
  return sumBy(arr, key) / arr.length;
}

/**
 * 获取数组最大值
 * @param {Array} arr 数组
 * @param {string|Function} key 字段或函数
 * @returns {any} 最大值项
 */
export function maxBy(arr, key) {
  if (!isArray(arr) || arr.length === 0) return undefined;

  return arr.reduce((max, item) => {
    const value = typeof key === 'function' ? key(item) : (key ? item[key] : item);
    const maxValue = typeof key === 'function' ? key(max) : (key ? max[key] : max);
    return value > maxValue ? item : max;
  });
}

/**
 * 获取数组最小值
 * @param {Array} arr 数组
 * @param {string|Function} key 字段或函数
 * @returns {any} 最小值项
 */
export function minBy(arr, key) {
  if (!isArray(arr) || arr.length === 0) return undefined;

  return arr.reduce((min, item) => {
    const value = typeof key === 'function' ? key(item) : (key ? item[key] : item);
    const minValue = typeof key === 'function' ? key(min) : (key ? min[key] : min);
    return value < minValue ? item : min;
  });
}

/**
 * 数组洗牌
 * @param {Array} arr 数组
 * @returns {Array} 洗牌后的新数组
 */
export function shuffle(arr) {
  if (!isArray(arr)) return [];

  const result = arr.slice();
  for (let i = result.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [result[i], result[j]] = [result[j], result[i]];
  }
  return result;
}

/**
 * 随机取样
 * @param {Array} arr 数组
 * @param {number} n 取样数量（可选）
 * @returns {any|Array} 取样结果
 */
export function sample(arr, n) {
  if (!isArray(arr)) return n === undefined ? undefined : [];
  if (arr.length === 0) return n === undefined ? undefined : [];

  // 如果没有指定n，返回单个元素
  if (n === undefined) {
    const randomIndex = Math.floor(Math.random() * arr.length);
    return arr[randomIndex];
  }

  if (n <= 0) return [];
  if (n >= arr.length) return shuffle(arr);

  const shuffled = shuffle(arr);
  return shuffled.slice(0, n);
}

/**
 * 数组取交集
 * @param {...Array} arrays 数组
 * @returns {Array} 交集数组
 */
export function intersection(...arrays) {
  if (arrays.length === 0) return [];
  if (arrays.length === 1) return isArray(arrays[0]) ? unique(arrays[0]) : [];

  const [first, ...rest] = arrays;
  if (!isArray(first)) return [];

  return unique(first).filter(item => {
    return rest.every(arr => isArray(arr) && arr.includes(item));
  });
}

/**
 * 数组取并集
 * @param {...Array} arrays 数组
 * @returns {Array} 并集数组
 */
export function union(...arrays) {
  const result = [];
  arrays.forEach(arr => {
    if (isArray(arr)) {
      result.push(...arr);
    }
  });
  return unique(result);
}

/**
 * 数组取差集
 * @param {Array} arr 主数组
 * @param {...Array} others 其他数组
 * @returns {Array} 差集数组
 */
export function difference(arr, ...others) {
  if (!isArray(arr)) return [];

  const otherItems = union(...others);
  return arr.filter(item => !otherItems.includes(item));
}

/**
 * 数组分页
 * @param {Array} arr 数组
 * @param {number} page 页码（从1开始）
 * @param {number} pageSize 页大小
 * @returns {Object} 分页结果
 */
export function paginate(arr, page = 1, pageSize = 10) {
  if (!isArray(arr)) return { data: [], total: 0, page: 1, pageSize, totalPages: 0 };

  const total = arr.length;
  const totalPages = Math.ceil(total / pageSize);
  const currentPage = Math.max(1, Math.min(page, totalPages));
  const startIndex = (currentPage - 1) * pageSize;
  const endIndex = startIndex + pageSize;
  const data = arr.slice(startIndex, endIndex);

  return {
    data,
    total,
    page: currentPage,
    pageSize,
    totalPages,
    hasNext: currentPage < totalPages,
    hasPrev: currentPage > 1
  };
}

/**
 * 数组转树形结构
 * @param {Array} arr 扁平数组
 * @param {string} idKey ID字段名
 * @param {string} parentIdKey 父ID字段名
 * @param {string} childrenKey 子节点字段名
 * @returns {Array} 树形结构数组
 */
export function arrayToTree(arr, idKey = 'id', parentIdKey = 'parentId', childrenKey = 'children') {
  if (!isArray(arr)) return [];

  const map = {};
  const result = [];

  // 创建映射
  arr.forEach(item => {
    map[item[idKey]] = { ...item, [childrenKey]: [] };
  });

  // 构建树形结构
  arr.forEach(item => {
    const node = map[item[idKey]];
    const parentId = item[parentIdKey];

    if (parentId && map[parentId]) {
      map[parentId][childrenKey].push(node);
    } else {
      result.push(node);
    }
  });

  return result;
}

/**
 * 树形结构转数组
 * @param {Array} tree 树形结构
 * @param {string} childrenKey 子节点字段名
 * @returns {Array} 扁平数组
 */
export function treeToArray(tree, childrenKey = 'children') {
  if (!isArray(tree)) return [];

  const result = [];

  function traverse(nodes, parentId = null) {
    nodes.forEach(node => {
      const { [childrenKey]: children, ...item } = node;
      if (parentId !== null) {
        item.parentId = parentId;
      }
      result.push(item);

      if (isArray(children) && children.length > 0) {
        traverse(children, item.id);
      }
    });
  }

  traverse(tree);
  return result;
}

/**
 * 移动数组元素
 * @param {Array} arr 数组
 * @param {number} fromIndex 源索引
 * @param {number} toIndex 目标索引
 * @returns {Array} 新数组
 */
export function move(arr, fromIndex, toIndex) {
  if (!isArray(arr)) return [];
  if (fromIndex < 0 || fromIndex >= arr.length) return arr.slice();
  if (toIndex < 0 || toIndex >= arr.length) return arr.slice();

  const result = arr.slice();
  const item = result.splice(fromIndex, 1)[0];
  result.splice(toIndex, 0, item);
  return result;
}

/**
 * 按属性或函数排序
 * @param {Array} arr 数组
 * @param {string|Function} iteratee 排序条件
 * @returns {Array} 排序后的数组
 */
export function sortBy(arr, iteratee) {
  if (!isArray(arr)) return [];

  const result = arr.slice();

  if (typeof iteratee === 'string') {
    return result.sort((a, b) => {
      const aVal = a[iteratee];
      const bVal = b[iteratee];
      if (aVal < bVal) return -1;
      if (aVal > bVal) return 1;
      return 0;
    });
  } else if (typeof iteratee === 'function') {
    return result.sort((a, b) => {
      const aVal = iteratee(a);
      const bVal = iteratee(b);
      if (aVal < bVal) return -1;
      if (aVal > bVal) return 1;
      return 0;
    });
  }

  return result;
}

/**
 * 移除数组中的假值
 * @param {Array} arr 数组
 * @returns {Array} 移除假值后的数组
 */
export function compact(arr) {
  if (!isArray(arr)) return [];
  return arr.filter(Boolean);
}

/**
 * 按条件分割数组
 * @param {Array} arr 数组
 * @param {Function} predicate 分割条件
 * @returns {Array} 包含两个数组的数组[满足条件的, 不满足条件的]
 */
export function partition(arr, predicate) {
  if (!isArray(arr) || typeof predicate !== 'function') return [[], []];

  const truthy = [];
  const falsy = [];

  arr.forEach(item => {
    if (predicate(item)) {
      truthy.push(item);
    } else {
      falsy.push(item);
    }
  });

  return [truthy, falsy];
}

/**
 * 找到最后满足条件的元素索引
 * @param {Array} arr 数组
 * @param {Function} predicate 条件函数
 * @returns {number} 索引，未找到返回-1
 */
export function findLastIndex(arr, predicate) {
  if (!isArray(arr) || typeof predicate !== 'function') return -1;

  for (let i = arr.length - 1; i >= 0; i--) {
    if (predicate(arr[i])) {
      return i;
    }
  }

  return -1;
}

/**
 * 计算数组元素之和
 * @param {Array} arr 数组
 * @returns {number} 和
 */
export function sum(arr) {
  if (!isArray(arr)) return 0;
  return arr.reduce((sum, val) => sum + (Number(val) || 0), 0);
}

/**
 * 计算数组元素的平均值
 * @param {Array} arr 数组
 * @returns {number} 平均值
 */
export function average(arr) {
  if (!isArray(arr) || arr.length === 0) return 0;
  return sum(arr) / arr.length;
}

/**
 * 找到数组中的最大值
 * @param {Array} arr 数组
 * @returns {any} 最大值
 */
export function max(arr) {
  if (!isArray(arr) || arr.length === 0) return undefined;
  return Math.max(...arr);
}

/**
 * 找到数组中的最小值
 * @param {Array} arr 数组
 * @returns {any} 最小值
 */
export function min(arr) {
  if (!isArray(arr) || arr.length === 0) return undefined;
  return Math.min(...arr);
}

// ========== Lodash风格的数组操作函数 ==========

/**
 * 获取数组第一个元素
 * @param {Array} arr 数组
 * @returns {any} 第一个元素
 */
export function first(arr) {
  if (!isArray(arr) || arr.length === 0) return undefined;
  return arr[0];
}

/**
 * head别名（同first）
 * @param {Array} arr 数组
 * @returns {any} 第一个元素
 */
export function head(arr) {
  return first(arr);
}

/**
 * 获取数组最后一个元素
 * @param {Array} arr 数组
 * @returns {any} 最后一个元素
 */
export function last(arr) {
  if (!isArray(arr) || arr.length === 0) return undefined;
  return arr[arr.length - 1];
}

/**
 * 获取数组第n个元素（支持负索引）
 * @param {Array} arr 数组
 * @param {number} n 索引
 * @returns {any} 第n个元素
 */
export function nth(arr, n = 0) {
  if (!isArray(arr) || arr.length === 0) return undefined;

  const index = n < 0 ? arr.length + n : n;
  return arr[index];
}

/**
 * 获取除最后一个元素外的所有元素
 * @param {Array} arr 数组
 * @returns {Array} 新数组
 */
export function initial(arr) {
  if (!isArray(arr) || arr.length === 0) return [];
  return arr.slice(0, -1);
}

/**
 * 获取除第一个元素外的所有元素
 * @param {Array} arr 数组
 * @returns {Array} 新数组
 */
export function tail(arr) {
  if (!isArray(arr) || arr.length === 0) return [];
  return arr.slice(1);
}

/**
 * 从数组开头截取n个元素
 * @param {Array} arr 数组
 * @param {number} n 数量
 * @returns {Array} 截取的数组
 */
export function take(arr, n = 1) {
  if (!isArray(arr) || n <= 0) return [];
  return arr.slice(0, n);
}

/**
 * 从数组末尾截取n个元素
 * @param {Array} arr 数组
 * @param {number} n 数量
 * @returns {Array} 截取的数组
 */
export function takeRight(arr, n = 1) {
  if (!isArray(arr) || n <= 0) return [];
  return arr.slice(-n);
}

/**
 * 从数组开头开始截取，直到predicate返回false
 * @param {Array} arr 数组
 * @param {Function} predicate 断言函数
 * @returns {Array} 截取的数组
 */
export function takeWhile(arr, predicate) {
  if (!isArray(arr) || typeof predicate !== 'function') return [];

  const result = [];
  for (let i = 0; i < arr.length; i++) {
    if (!predicate(arr[i], i, arr)) break;
    result.push(arr[i]);
  }
  return result;
}

/**
 * 从数组末尾开始截取，直到predicate返回false
 * @param {Array} arr 数组
 * @param {Function} predicate 断言函数
 * @returns {Array} 截取的数组
 */
export function takeRightWhile(arr, predicate) {
  if (!isArray(arr) || typeof predicate !== 'function') return [];

  const result = [];
  for (let i = arr.length - 1; i >= 0; i--) {
    if (!predicate(arr[i], i, arr)) break;
    result.unshift(arr[i]);
  }
  return result;
}

/**
 * 从数组开头删除n个元素
 * @param {Array} arr 数组
 * @param {number} n 数量
 * @returns {Array} 删除后的新数组
 */
export function drop(arr, n = 1) {
  if (!isArray(arr) || n <= 0) return arr.slice();
  return arr.slice(n);
}

/**
 * 从数组末尾删除n个元素
 * @param {Array} arr 数组
 * @param {number} n 数量
 * @returns {Array} 删除后的新数组
 */
export function dropRight(arr, n = 1) {
  if (!isArray(arr) || n <= 0) return arr.slice();
  return arr.slice(0, -n);
}

/**
 * 从数组开头开始删除，直到predicate返回false
 * @param {Array} arr 数组
 * @param {Function} predicate 断言函数
 * @returns {Array} 删除后的新数组
 */
export function dropWhile(arr, predicate) {
  if (!isArray(arr) || typeof predicate !== 'function') return arr.slice();

  let index = 0;
  while (index < arr.length && predicate(arr[index], index, arr)) {
    index++;
  }
  return arr.slice(index);
}

/**
 * 从数组末尾开始删除，直到predicate返回false
 * @param {Array} arr 数组
 * @param {Function} predicate 断言函数
 * @returns {Array} 删除后的新数组
 */
export function dropRightWhile(arr, predicate) {
  if (!isArray(arr) || typeof predicate !== 'function') return arr.slice();

  let index = arr.length - 1;
  while (index >= 0 && predicate(arr[index], index, arr)) {
    index--;
  }
  return arr.slice(0, index + 1);
}

/**
 * 排除数组中的指定值
 * @param {Array} arr 数组
 * @param {...any} values 要排除的值
 * @returns {Array} 新数组
 */
export function without(arr, ...values) {
  if (!isArray(arr)) return [];
  return arr.filter(item => !values.includes(item));
}

/**
 * 移除数组中的指定值（修改原数组）
 * @param {Array} arr 数组
 * @param {...any} values 要移除的值
 * @returns {Array} 原数组
 */
export function pull(arr, ...values) {
  if (!isArray(arr)) return [];

  for (let i = arr.length - 1; i >= 0; i--) {
    if (values.includes(arr[i])) {
      arr.splice(i, 1);
    }
  }
  return arr;
}

/**
 * 移除数组中所有指定值
 * @param {Array} arr 数组
 * @param {Array} values 要移除的值数组
 * @returns {Array} 原数组
 */
export function pullAll(arr, values) {
  if (!isArray(arr) || !isArray(values)) return arr;
  return pull(arr, ...values);
}

/**
 * 按条件移除数组中的值
 * @param {Array} arr 数组
 * @param {Array} values 要移除的值数组
 * @param {string|Function} iteratee 比较条件
 * @returns {Array} 原数组
 */
export function pullAllBy(arr, values, iteratee) {
  if (!isArray(arr) || !isArray(values)) return arr;

  const getKey = typeof iteratee === 'function'
    ? iteratee
    : (item) => item[iteratee];

  const valuesToRemove = values.map(getKey);

  for (let i = arr.length - 1; i >= 0; i--) {
    if (valuesToRemove.includes(getKey(arr[i]))) {
      arr.splice(i, 1);
    }
  }
  return arr;
}

/**
 * 移除数组中指定索引的元素
 * @param {Array} arr 数组
 * @param {...number} indexes 索引
 * @returns {Array} 被移除的元素数组
 */
export function pullAt(arr, ...indexes) {
  if (!isArray(arr)) return [];

  const removed = [];
  const validIndexes = indexes.filter(i => i >= 0 && i < arr.length).sort((a, b) => b - a);

  validIndexes.forEach(index => {
    removed.unshift(...arr.splice(index, 1));
  });

  return removed;
}

/**
 * 按条件移除元素并返回被移除的元素
 * @param {Array} arr 数组
 * @param {Function} predicate 条件函数
 * @returns {Array} 被移除的元素数组
 */
export function remove(arr, predicate) {
  if (!isArray(arr) || typeof predicate !== 'function') return [];

  const removed = [];
  for (let i = arr.length - 1; i >= 0; i--) {
    if (predicate(arr[i], i, arr)) {
      removed.unshift(...arr.splice(i, 1));
    }
  }
  return removed;
}

/**
 * 数组转置（将多个数组的对应位置元素组合成新数组）
 * @param {...Array} arrays 数组
 * @returns {Array} 转置后的数组
 */
export function zip(...arrays) {
  if (arrays.length === 0) return [];

  const maxLength = Math.max(...arrays.map(arr => isArray(arr) ? arr.length : 0));
  const result = [];

  for (let i = 0; i < maxLength; i++) {
    result.push(arrays.map(arr => isArray(arr) ? arr[i] : undefined));
  }

  return result;
}

/**
 * 将转置后的数组还原
 * @param {Array} arr 转置后的数组
 * @returns {Array} 还原后的数组
 */
export function unzip(arr) {
  if (!isArray(arr) || arr.length === 0) return [];
  return zip(...arr);
}

/**
 * 按条件执行zip
 * @param {...Array} arrays 数组
 * @param {Function} iteratee 处理函数
 * @returns {Array} 处理后的数组
 */
export function zipWith(...arrays) {
  if (arrays.length === 0) return [];

  const iteratee = typeof arrays[arrays.length - 1] === 'function'
    ? arrays.pop()
    : (...args) => args;

  const zipped = zip(...arrays);
  return zipped.map(group => iteratee(...group));
}

/**
 * 数组对称差集（只在其中一个数组中出现的元素）
 * @param {...Array} arrays 数组
 * @returns {Array} 对称差集数组
 */
export function xor(...arrays) {
  if (arrays.length === 0) return [];

  const allItems = arrays.reduce((acc, arr) => {
    if (isArray(arr)) {
      arr.forEach(item => {
        const index = acc.findIndex(x => x.value === item);
        if (index === -1) {
          acc.push({ value: item, count: 1 });
        } else {
          acc[index].count++;
        }
      });
    }
    return acc;
  }, []);

  return allItems.filter(item => item.count === 1).map(item => item.value);
}

/**
 * 按条件的数组对称差集
 * @param {...Array} arrays 数组和iteratee
 * @returns {Array} 对称差集数组
 */
export function xorBy(...arrays) {
  if (arrays.length === 0) return [];

  const iteratee = typeof arrays[arrays.length - 1] === 'function'
    ? arrays.pop()
    : (x) => x;

  const allItems = arrays.reduce((acc, arr) => {
    if (isArray(arr)) {
      arr.forEach(item => {
        const key = iteratee(item);
        const index = acc.findIndex(x => x.key === key);
        if (index === -1) {
          acc.push({ value: item, key, count: 1 });
        } else {
          acc[index].count++;
        }
      });
    }
    return acc;
  }, []);

  return allItems.filter(item => item.count === 1).map(item => item.value);
}

/**
 * 使用比较器去重
 * @param {Array} arr 数组
 * @param {Function} comparator 比较器函数
 * @returns {Array} 去重后的数组
 */
export function uniqWith(arr, comparator) {
  if (!isArray(arr) || typeof comparator !== 'function') return arr.slice();

  const result = [];
  arr.forEach(item => {
    if (!result.some(existing => comparator(existing, item))) {
      result.push(item);
    }
  });
  return result;
}

/**
 * 填充数组
 * @param {Array} arr 数组
 * @param {any} value 填充值
 * @param {number} start 起始位置
 * @param {number} end 结束位置
 * @returns {Array} 填充后的数组
 */
export function fill(arr, value, start = 0, end) {
  if (!isArray(arr)) return [];

  const result = arr.slice();
  const len = result.length;
  const startIndex = start < 0 ? Math.max(len + start, 0) : Math.min(start, len);
  const endIndex = end === undefined ? len : (end < 0 ? Math.max(len + end, 0) : Math.min(end, len));

  for (let i = startIndex; i < endIndex; i++) {
    result[i] = value;
  }

  return result;
}

/**
 * 映射并扁平化数组一层
 * @param {Array} arr 数组
 * @param {Function} iteratee 映射函数
 * @returns {Array} 扁平化后的数组
 */
export function flatMap(arr, iteratee) {
  if (!isArray(arr)) return [];

  const fn = typeof iteratee === 'function' ? iteratee : (x) => x;
  return arr.reduce((acc, item, index) => {
    const result = fn(item, index, arr);
    if (isArray(result)) {
      acc.push(...result);
    } else {
      acc.push(result);
    }
    return acc;
  }, []);
}

/**
 * 映射并深度扁平化数组
 * @param {Array} arr 数组
 * @param {Function} iteratee 映射函数
 * @returns {Array} 扁平化后的数组
 */
export function flatMapDeep(arr, iteratee) {
  if (!isArray(arr)) return [];

  const fn = typeof iteratee === 'function' ? iteratee : (x) => x;
  return arr.reduce((acc, item, index) => {
    const result = fn(item, index, arr);
    if (isArray(result)) {
      acc.push(...flattenDeep(result));
    } else {
      acc.push(result);
    }
    return acc;
  }, []);
}

/**
 * 映射并按指定深度扁平化数组
 * @param {Array} arr 数组
 * @param {Function} iteratee 映射函数
 * @param {number} depth 深度
 * @returns {Array} 扁平化后的数组
 */
export function flatMapDepth(arr, iteratee, depth = 1) {
  if (!isArray(arr)) return [];

  const fn = typeof iteratee === 'function' ? iteratee : (x) => x;
  return arr.reduce((acc, item, index) => {
    const result = fn(item, index, arr);
    if (isArray(result)) {
      acc.push(...flatten(result, depth));
    } else {
      acc.push(result);
    }
    return acc;
  }, []);
}

/**
 * 查找元素的索引
 * @param {Array} arr 数组
 * @param {any} value 要查找的值
 * @param {number} fromIndex 起始索引
 * @returns {number} 索引，未找到返回-1
 */
export function indexOf(arr, value, fromIndex = 0) {
  if (!isArray(arr)) return -1;
  return arr.indexOf(value, fromIndex);
}

/**
 * 从右向左查找元素的索引
 * @param {Array} arr 数组
 * @param {any} value 要查找的值
 * @param {number} fromIndex 起始索引
 * @returns {number} 索引，未找到返回-1
 */
export function lastIndexOf(arr, value, fromIndex) {
  if (!isArray(arr)) return -1;
  return fromIndex === undefined ? arr.lastIndexOf(value) : arr.lastIndexOf(value, fromIndex);
}

/**
 * 反转数组
 * @param {Array} arr 数组
 * @returns {Array} 反转后的新数组
 */
export function reverse(arr) {
  if (!isArray(arr)) return [];
  return arr.slice().reverse();
}

/**
 * 数组连接成字符串
 * @param {Array} arr 数组
 * @param {string} separator 分隔符
 * @returns {string} 连接后的字符串
 */
export function join(arr, separator = ',') {
  if (!isArray(arr)) return '';
  return arr.join(separator);
}

/**
 * 从键值对数组创建对象
 * @param {Array} pairs 键值对数组
 * @returns {Object} 对象
 */
export function fromPairs(pairs) {
  if (!isArray(pairs)) return {};

  const result = {};
  pairs.forEach(pair => {
    if (isArray(pair) && pair.length >= 2) {
      result[pair[0]] = pair[1];
    }
  });
  return result;
}
